package com.elective.courseselect.service.impl;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.elective.courseselect.dao.AnswerDao;
import com.elective.courseselect.dao.QuestionDao;
import com.elective.courseselect.dao.QuestionnaireDao;
import com.elective.courseselect.entity.*;
import com.elective.courseselect.enums.QuestionnaireType;
import com.elective.courseselect.service.*;
import com.elective.courseselect.serviceUtils.CourseUtils;
import com.elective.courseselect.serviceUtils.QuestionUtils;
import com.elective.courseselect.serviceUtils.StuCourseUtils;
import com.elective.courseselect.serviceUtils.UserUtils;
import com.elective.courseselect.utils.PageUtils;
import com.elective.courseselect.utils.Query;
import com.elective.courseselect.utils.R;
import com.elective.status.StatusCode;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;


@Service("answerService")
@Transactional(rollbackFor = Exception.class)
public class AnswerServiceImpl extends ServiceImpl<AnswerDao, AnswerEntity> implements AnswerService {

    @Autowired
    QuestionService questionService;

    @Autowired
    StudentService studentService;

    @Autowired
    QuestionDao questionDao;

    @Autowired
    QuestionnaireService questionnaireService;

    @Autowired
    QuestionnaireDao questionnaireDao;

    @Autowired
    StudentCharacterService studentCharacterService;

    @Autowired
    CourseService courseService;

    @Autowired
    StudentCourseService studentCourseService;

    @Autowired
    AnswerService answerService;

    @Autowired
    AnswerDao answerDao;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AnswerEntity> page = this.page(
                new Query<AnswerEntity>().getPage(params),
                new QueryWrapper<AnswerEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public R inputPersonalityQuestionnaire(InputAnswerListVo inputAnswerListVo) {

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("questionnaireId", inputAnswerListVo.getQuestionnaireId());
        JSONArray jsonArray = new JSONArray();


        jsonObject.put("courseId", inputAnswerListVo.getCourseId());

        List<InputAnswerVo> inputAnswerVoList = inputAnswerListVo.getInputAnswerVoList();
        Integer totalScore = 0;
        Set<String> characterSet = new HashSet<>();
        QuestionnaireEntity questionnaireEntity = questionnaireService.getById(inputAnswerListVo.getQuestionnaireId());

        List<QuestionEntity> questionEntities = QuestionUtils.searchQuestionListByQuestionnaireId(inputAnswerListVo.getQuestionnaireId());
        for (InputAnswerVo inputAnswerVo : inputAnswerVoList) {
            Boolean flag = false;
            QuestionEntity questionEntity = questionService.getById(inputAnswerVo.getQuestionId());
            for (QuestionEntity entity : questionEntities) {
                if (entity.getId() == questionEntity.getId()) {
                    flag = true;
                    break;
                }
            }
            if (flag == false) {
                return R.error(StatusCode.ERROR,"提交的此题" + questionEntity.getId() + "并不属于" + inputAnswerListVo.getQuestionnaireId() + "此套问卷");
            }

            //回传学生填入此题分值
            Integer questionEntityValue = questionEntity.getValue();
            if (null == questionEntityValue) {
                questionEntityValue = 0 ;
            }
            inputAnswerVo.setQuestionValue(questionEntityValue);


            //主观题标准答案为null,预防空指针
            JSONArray questionReferenceArray = JSONObject.parseArray(questionEntity.getReference());
            if (CollectionUtils.isEmpty(questionReferenceArray)) {
                questionReferenceArray = new JSONArray();
            }

            // 答案正确
            if (questionReferenceArray.equals(inputAnswerVo.getStuInputAnswer())) {
                // 性格调查问卷 性格调查问卷没有分值
                if (questionnaireEntity.getType() == QuestionnaireType.PERSONALITY_QUESTIONNAIRE) {
                    characterSet.add(questionEntity.getCharactersId());
                    inputAnswerVo.setIsCorrect(true);
                }
                // 课程意愿
                if (questionnaireEntity.getType() == QuestionnaireType.COURSE_WILL_QUESTIONNAIRE) {
                    Integer value = questionEntity.getValue();
                    if (null == value) {
                        value = 0;
                    }
                    totalScore += value;
                    inputAnswerVo.setIsCorrect(true);
                    inputAnswerVo.setStuScore(value);
                }
            }
            // 答案不正确
            else{
                inputAnswerVo.setIsCorrect(false);
                inputAnswerVo.setStuScore(0);
            }
        }
        jsonArray.addAll(inputAnswerListVo.getInputAnswerVoList());
        jsonObject.put("solution", jsonArray);
        // 性格调查问卷
        if (questionnaireEntity.getType() == QuestionnaireType.PERSONALITY_QUESTIONNAIRE) {

            QueryWrapper<StudentCharacterEntity> wrapper = new QueryWrapper();
            wrapper.eq("student_id", inputAnswerListVo.getUserId());
            StudentCharacterEntity studentCharacterEntity = studentCharacterService.getOne(wrapper);
            List<String> list = new ArrayList<>();
            if (null != studentCharacterEntity) {
                list  = Arrays.asList(studentCharacterEntity.getCharacterId().split(","));
            }
            Set<String> resSet = new HashSet<>();

            //保存原本存储的性格标签id
            resSet.addAll(list);

            if (!CollectionUtils.isEmpty(characterSet)) {
                for (String ids : characterSet) {
                    for (String id : ids.split(",")) {
                        resSet.add(id);
                    }
                }
            }
            // 更新学生性格调查问卷
            studentCharacterEntity = new StudentCharacterEntity();
            studentCharacterEntity.setStudentId(inputAnswerListVo.getUserId());
            studentCharacterEntity.setCharacterId(StringUtils.join(resSet, ","));
            studentCharacterService.updateStuChar(studentCharacterEntity);



            AnswerEntity answerEntity = new AnswerEntity();
            answerEntity.setStudentId(inputAnswerListVo.getUserId());
            answerEntity.setQuestionnaireId(inputAnswerListVo.getQuestionnaireId());
            answerEntity.setTime(new Date());
            //性格调查问卷没有总分,只有性格标签
            //answerEntity.setTotalScore(totalScore);
            answerEntity.setSolution(jsonObject.toString());

            QueryWrapper<AnswerEntity> answerEntityWrapper = new QueryWrapper();
            answerEntityWrapper.eq("student_id", answerEntity.getStudentId());
            wrapper.eq("questionnaire_id", inputAnswerListVo.getQuestionnaireId());
            answerEntity.setStatus(StatusCode.ANSWER_PRE_SELECT);
            answerService.saveOrUpdate(answerEntity, answerEntityWrapper);
        }

        // 课程调查问卷
        if (questionnaireEntity.getType() == QuestionnaireType.COURSE_WILL_QUESTIONNAIRE) {
            AnswerEntity answerEntity = new AnswerEntity();
            answerEntity.setStudentId(inputAnswerListVo.getUserId());
            answerEntity.setQuestionnaireId(inputAnswerListVo.getQuestionnaireId());
            answerEntity.setTime(new Date());
            answerEntity.setTotalScore(totalScore);
            answerEntity.setSolution(jsonObject.toString());

            QueryWrapper<AnswerEntity> wrapper = new QueryWrapper();
            wrapper.eq("student_id", answerEntity.getStudentId());
            wrapper.eq("questionnaire_id", inputAnswerListVo.getQuestionnaireId());
            answerEntity.setStatus(StatusCode.ANSWER_PRE_SELECT);
            answerService.saveOrUpdate(answerEntity, wrapper);
        }

        return R.ok("填写问卷成功");
    }

    @Override
    public R inputClassQuestionnaire(InputAnswerListVo inputAnswerListVo) {
        R r = inputPersonalityQuestionnaire(inputAnswerListVo);
        return r;
    }

    @Override
    public List<AnswerEntity> searchStuAnswerListByQuestionnaireId(Integer questionnaireId) {
        QueryWrapper<AnswerEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("questionnaire_id", questionnaireId);
        List<AnswerEntity> list = this.list(wrapper);
        for (int i = 0; i < list.size(); i++) {
            AnswerEntity answerEntity = list.get(i);
            Boolean abandon = UserUtils.isAbandon(answerEntity.getStudentId());
            if (abandon) {
                list.remove(i);
                continue;
            }
            answerEntity.setSolutionByJSON((JSONObject) JSONObject.parse(answerEntity.getSolution()));
        }
        return list;
    }

    @Override
    public AnswerListVo searchStuAnswerDetails(Integer questionnaireId , Integer userId) {
        // 传入问卷id ， 查询该问卷所有题目
        List<QuestionEntity> questionEntityList = QuestionUtils.searchQuestionListByQuestionnaireId(questionnaireId);

        QueryWrapper<AnswerEntity> answerEntityQueryWrapper = new QueryWrapper<>();
        answerEntityQueryWrapper.eq("student_id", userId);
        answerEntityQueryWrapper.eq("questionnaire_id", questionnaireId);
        // 某学生回答 该问卷情况
        AnswerEntity answerEntity = answerService.getOne(answerEntityQueryWrapper);



        AnswerListVo answerListVo = new AnswerListVo();
        List<AnswerVo> answerVos = new ArrayList<>();

        for (QuestionEntity questionEntity : questionEntityList) {
            JSONObject object = JSONObject.parseObject(answerEntity.getSolution(), JSONObject.class);
            ArrayList<String> StuInputAnsWer = new ArrayList<>();
            AnswerVo answerVo = new AnswerVo();
            for (Object solution : object.getJSONArray("solution")) {
                JSONObject parse = JSONObject.parseObject(solution.toString(),JSONObject.class);
                //学生回答的question id
                Integer questionId = parse.getInteger("questionId");
                // 如果回答问题和试卷id 相同，代表回答过该题
                if (questionEntity.getId() == questionId) {
                    JSONArray stuInputAnswer = parse.getJSONArray("stuInputAnswer");
                    for (Object o : stuInputAnswer) {
                        // 学生此问题 所填答案
                        StuInputAnsWer.add(String.valueOf(o));
                    }
                    //answer表信息
                    answerVo.setSolution(StuInputAnsWer);
                    answerVo.setStuScore(parse.getInteger("stuScore"));
                    answerVo.setIsCorrect(parse.getBoolean("isCorrect"));
                    //question表信息
                    answerVo.setQuestionId(questionEntity.getId());
                    answerVo.setQuestionType(questionEntity.getType());
                    answerVo.setQuestionValue(questionEntity.getValue());
                    answerVo.setQuestionOption(JSONObject.parseArray(questionEntity.getOption(), String.class));
                    answerVo.setQuestionReference(JSONObject.parseArray(questionEntity.getReference(), String.class));
                    answerVo.setQuestionCharactersId(questionEntity.getCharactersId());
                    answerVo.setQuestionTitle(questionDao.selectById(questionEntity.getId()).getTitle());
                    //自定义消息
                    answerVo.setMsg("此问题被回答过");
                    break;
                }
                // 没有回答过此题目
                else{
                    continue;
                }
            }
            // null == answerVo.getMsg代表没有被回答过。
            if (null == answerVo.getMsg()) {
                //没有答案肯定是错
                answerVo.setIsCorrect(false);
                //代表分值设为0
                answerVo.setStuScore(0);
                answerVo.setQuestionId(questionEntity.getId());
                answerVo.setQuestionType(questionEntity.getType());
                answerVo.setQuestionValue(questionEntity.getValue());
                answerVo.setQuestionOption(JSONObject.parseArray(questionEntity.getOption(), String.class));
                answerVo.setQuestionReference(JSONObject.parseArray(questionEntity.getReference(), String.class));
                answerVo.setQuestionTitle(questionDao.selectById(questionEntity.getId()).getTitle());
                answerVo.setMsg("此问题未被回答过");
            }

            answerVos.add(answerVo);
        }
        answerListVo.setAnswerId(answerEntity.getId());
        answerListVo.setTime(answerEntity.getTime());
        answerListVo.setStudentId(answerEntity.getStudentId());
        answerListVo.setQuestionnaireId(answerEntity.getQuestionnaireId());
        answerListVo.setTotalScore(answerEntity.getTotalScore());
        answerListVo.setAnswerVos(answerVos);
        return answerListVo;
    }

    /**
     * 结束预选
     * @author Lee
     * @date 2021/10/24 20:35
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized void finishPrimary() {
        Map<Integer, List<AnswerEntity>> tempCalMap = new ConcurrentHashMap<>();
        List<Integer> noFindQuestionnaire = new ArrayList<>();
        QueryWrapper<AnswerEntity> answerEntityQueryWrapper = new QueryWrapper<>();
        answerEntityQueryWrapper.eq("status", StatusCode.ANSWER_PRE_SELECT);
        List<AnswerEntity> list = answerService.list(answerEntityQueryWrapper);
        List<Integer> needDelInt = new ArrayList<>();
        //组装统计回答列表中,根据课程id,统计答题数据
        for (AnswerEntity answerEntity : list) {
            Integer courseId = QuestionUtils.baseOfQuestionnaireIdGetCourseId(answerEntity.getQuestionnaireId());
            //如果查到是空的,说明没有这套问卷,或者这套问卷的课程被干掉了。
            if (null == courseId) {
                //稍后清理
                noFindQuestionnaire.add(answerEntity.getId());
            }else{
                if (null != tempCalMap.get(courseId) && tempCalMap.containsKey(courseId)) {
                    tempCalMap.get(courseId).add(answerEntity);
                }else{
                    ArrayList<AnswerEntity> tempList = new ArrayList<>();
                    tempList.add(answerEntity);
                    tempCalMap.put(courseId, tempList);
                }
            }
        }



        for (Map.Entry<Integer, List<AnswerEntity>> entry : tempCalMap.entrySet()) {
            Integer courseId = entry.getKey();
            //得到降序的成绩排名
            List<AnswerEntity> collect = entry.getValue().stream().sorted(Comparator.comparing(AnswerEntity::getTotalScore,Comparator.reverseOrder())).collect(Collectors.toList());
            //根据课程id得到课余量
            CourseEntity courseNumRemaining = CourseUtils.getCourseNumRemaining(courseService.getById(courseId));
            //课余量
            Integer numRemaining = courseNumRemaining.getNumRemaining();
            //预选答题人数,小于课余量,说明课程,充足,全部都纳入课程就好。
            if (collect.size() <= numRemaining) {
                for (AnswerEntity answerEntity : collect) {
                    QueryWrapper<StudentCourseEntity> studentEntityQueryWrapper = new QueryWrapper<>();
                    studentEntityQueryWrapper.eq("student_id", answerEntity.getStudentId());
                    StudentCourseEntity stuCourseOne = studentCourseService.getOne(studentEntityQueryWrapper);
                    if (null == stuCourseOne) {
                        StudentCourseEntity studentCourseEntity = new StudentCourseEntity();
                        studentCourseEntity.setCourseId(courseId.toString());
                        studentCourseEntity.setStudentId(answerEntity.getStudentId());
                        studentCourseService.save(studentCourseEntity);
                        answerEntity.setStatus(StatusCode.ANSWER_SUCCESS_SELECT);
                        answerService.updateById(answerEntity);
                    }else{
                        stuCourseOne.getCourseId();
                        stuCourseOne = StuCourseUtils.modifyStuCourse(stuCourseOne, courseId);
                        //设置已选上状态
                        answerEntity.setStatus(StatusCode.ANSWER_SUCCESS_SELECT);
                        answerService.updateById(answerEntity);
                    }
                }
            }
            //人数多余课余量,按成绩加人
            else {
                for (int i = 0; i < numRemaining; i++) {
                    //这里得到最上面的一条，因为已经排过序了。最上面的一条就是成绩最好的
                    AnswerEntity answerEntity = collect.get(0);
                    QueryWrapper<StudentCourseEntity> studentEntityQueryWrapper = new QueryWrapper<>();
                    studentEntityQueryWrapper.eq("student_id", answerEntity.getStudentId());
                    StudentCourseEntity stuCourseOne = studentCourseService.getOne(studentEntityQueryWrapper);
                    if (null == stuCourseOne) {
                        StudentCourseEntity studentCourseEntity = new StudentCourseEntity();
                        studentCourseEntity.setCourseId(courseId.toString());
                        studentCourseEntity.setStudentId(answerEntity.getStudentId());
                        studentCourseService.save(studentCourseEntity);
                        answerEntity.setStatus(StatusCode.ANSWER_SUCCESS_SELECT);
                        answerService.updateById(answerEntity);
                    }else{
                        stuCourseOne.getCourseId();
                        stuCourseOne = StuCourseUtils.modifyStuCourse(stuCourseOne, courseId);
                        //设置已选上状态
                        answerEntity.setStatus(StatusCode.ANSWER_SUCCESS_SELECT);
                        answerService.updateById(answerEntity);
                        //删除已选的集合
                    }
                    collect.remove(0);
                }
                //后面都是名额不够的.设置预选失败
                for (AnswerEntity answerEntity : collect) {
                    answerEntity.setStatus(StatusCode.ANSWER_FAIL_SELECT);
                    answerService.updateById(answerEntity);
                    answerService.removeById(answerEntity);
                }
            }
        }

        //处理找不到问卷或者课程的回答。
        for (Integer answerId : noFindQuestionnaire) {
            AnswerEntity answerEntity = answerService.getById(answerId);
            answerEntity.setStatus(StatusCode.ANSWER_FAIL_SELECT);
            answerService.updateById(answerEntity);
            answerService.removeById(answerEntity);
        }
    }
}